package cn.getech.data.metadata.utils;


import cn.getech.data.development.utils.SendEMailUtil;
import cn.getech.data.development.utils.spring.SpringContextUtil;
import cn.getech.data.intelligence.common.utils.DateUtils;
import cn.getech.data.metadata.entity.CollectionNotificationHistory;
import cn.getech.data.metadata.entity.CollectionNotificationUser;
import cn.getech.data.metadata.service.CollectionNotificationHistoryService;
import cn.getech.data.metadata.service.CollectionNotificationUserGroupService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public class SendEmailDelayUtil {

    private static DelayQueue<RunTask> queue = new DelayQueue<>();

    public static void init(){
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        //历史发送内容
        CollectionNotificationHistoryService collectionNotification = SpringContextUtil.getBean(CollectionNotificationHistoryService.class);
        //获取免打扰时间
        CollectionNotificationUserGroupService bean = SpringContextUtil.getBean(CollectionNotificationUserGroupService.class);
        //发送邮件
        SendEMailUtil sendEMailUtil = SpringContextUtil.getBean(SendEMailUtil.class);
        //获取所有的待发送邮件
        List<CollectionNotificationHistory> collectionNotificationHistories = collectionNotification.queryCollectionNotificationHistory("2");
        if (CollectionUtils.isNotEmpty(collectionNotificationHistories)) {
            for(CollectionNotificationHistory collectionNotificationHistory:collectionNotificationHistories){
                CollectionNotificationUser byId = bean.getById(collectionNotificationHistory.getNotificationUserId());
                //添加到延时队列里面
                log.info("启动加入邮件：{}", byId.getId(), DateUtils.format(byId.getNoDisturbingEnd(),DateUtils.DATE_TIME_PATTERN));
                addTask(byId.getId(), byId.getNoDisturbingEnd().getTime(),"");
            }
        }
        singleThreadPool.execute(new Consumer(queue, collectionNotification,sendEMailUtil));
    }
    /**
     * @param taskId  任务id
     * @param runTime 执行时间  对应 runTime  时间
     * @Description: 添加任务类型
     * @return: void
     */
    public static void addTask(Long taskId, Long runTime,String type) {
        log.info("运行加入邮件：{}", taskId, DateUtils.format(new Date(runTime),DateUtils.DATE_TIME_PATTERN));
        RunTask t = new RunTask(taskId, runTime, type);
        addTask(t);
        log.info("邮件面打扰延时任务：{}", taskId, DateUtils.format(new Date(runTime),DateUtils.DATE_TIME_PATTERN));
    }

    /**
     * @param taskId  任务id
     * @param runTime 对应 effectiveDeadline  时间
     * @Title: remove
     * @Description: 删除任务
     * @return: void
     */
    public static void remove(Long taskId, Long runTime,String type) {
        RunTask t = new RunTask(taskId, runTime,type);
        remove(t);
    }

    /**
     * @param t
     * @Title: addTask
     * @Description: 添加任务
     * @return: void
     */
    public static void addTask(RunTask t) {
        queue.put(t);
    }

    /**
     * @param t 任务
     * @Title: remove
     * @Description: 删除任务
     * @return: void
     */
    public static void remove(RunTask t) {
        queue.remove(t);
    }

    public static class Consumer implements Runnable {
        // 延时队列 ,消费者从其中获取消息进行消费
        private DelayQueue<RunTask> queue;

        private SendEMailUtil sendEMailUtil;

        private CollectionNotificationHistoryService collectionNotification;

        public Consumer(DelayQueue<RunTask> queue,CollectionNotificationHistoryService collectionNotificationUserGroupService,SendEMailUtil sendEMailUtil) {
            this.queue = queue;
            this.collectionNotification=collectionNotificationUserGroupService;
            this.sendEMailUtil=sendEMailUtil;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    RunTask take = queue.take();
                    //查询所有的未发送的邮件
                    log.info("执行运行加入邮件：{}", take.getTaskId());
                    List<CollectionNotificationHistory> collectionNotificationHistories = collectionNotification.queryCollectionNotificationHistory("2");
                    if(take.getTaskId()!=null){
                        if (CollectionUtils.isNotEmpty(collectionNotificationHistories)) {
                            for(CollectionNotificationHistory collectionNotificationHistory:collectionNotificationHistories){
                                //到时间了  更新历史记录的同时 发送邮件
                                if(collectionNotificationHistory.getNotificationUserId()==take.getTaskId()){
                                    try {
                                        sendEMailUtil.createSimpleMail(collectionNotificationHistory.getEmail(),collectionNotificationHistory.getNotificationTitle(),collectionNotificationHistory.getNotificationContent());
                                        log.info("执行发送邮件：{}", take.getTaskId());
                                        collectionNotificationHistory.setUpdateTime(new Date());
                                        collectionNotificationHistory.setNotificationFlag(1);
                                        collectionNotification.updateCollectionNotificationHistory(collectionNotificationHistory);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                } catch (InterruptedException e) {

                }
            }
        }
    }

    public static class RunTask implements Delayed {
        //任务id
        private Long taskId;
        //类型
        private String type;
        //执行时间
        private Long runTime;
        /**
         * 免打扰时间 id
         * @param taskId    面打扰时间的id
         * @param runTime   打扰时间
         * @param type      类型
         */
        public RunTask(Long taskId, Long runTime,String type) {
            this.taskId = taskId;
            this.runTime = runTime;
            this.type = type;
        }
        @Override
        public int compareTo(Delayed o) {
            RunTask rt = (RunTask) o;
            long diff = this.runTime - rt.runTime;
            if (diff > 0) {
                return 1;
            } else if (diff < 0) {
                return -1;
            } else {
                return 0;
            }
        }
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.runTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }
        public Long getTaskId() {
            return taskId;
        }
    }
}
